package com.diuse;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by carey on 2016/7/9 0009.
 * jvm运行参数
 * -verbose:gc -Xms20M -Xmx20M -Xmn10M -XX:+PrintGCDetails -XX:SurvivorRatio=8
 * 堆大小设置为20M，新生代10M，新生代中可用的是9M，剩余1M用来垃圾收集器回收的交换区
 *
 * 第一条输出的小gc日志为： [GC [PSYoungGen: 7768K->1016K(9216K)] 7768K->5289K(19456K), 0.0129323 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]
 *      这次的小gc实际时间为0.01s
 *      新生代gc：垃圾收集工作前被占用的空间为7768K,收集后剩下了1016K,回收了6752K
 *          位置      工作前被占用的空间   工作后被占空的空间   总共的空间       回收的空间
 *          新生代：     7768K                  1016K         9216K            6752K
 *          整个堆       7768K                  5289K         19456K           2479K(这才是真正被回收掉的空间)
 *          新生代被回收的空间 —— 整个堆回收的空间 = 新生代被交换到老生带的空间。
 *
 *  第一条输出的大gc日志为： [Full GC [PSYoungGen: 9208K->0K(9216K)] [ParOldGen: 10232K->9816K(10240K)] 19440K->9816K(19456K) [PSPermGen: 3042K->3041K(21504K)], 0.3411768 secs] [Times: user=0.45 sys=0.00, real=0.34 secs]
 *      这次大gc实际时间为0.34s
 *
 *      其实这条日志并不是第一次大gc的,从系统时间可以看出来。
 *          位置      工作前被占用的空间   工作后被占空的空间  总共的空间   回收的空间
 *          新生代：     9208K                  0K           9216K       9208K
 *          老生代       10232K                9816K        10240K        416k
 *          整个堆       19440K                  9816K      19456K       9624K(这才是真正被回收掉的空间)
 *          方法区       3042K                   3041K      21504K         1K
 *
 *          新生代升级到老生代的空间为9208K+416K-9624k = 0
 *
 *          一次大gc肯定会引发一次小gc。大gc会回收方法区，而小gc不会。
 *
 *   疑惑点:
 *      1. 这段代码看上起没有可以被回收的变量，为什么还是会有空间能够被回收？
 *      2. gc的日志不是按照时间顺序来的，应该是会用队列或者数组来实现，难道是有多条线程用来打印？
 *      3. 从后面几条的日志来看，一次大gc还没有完成，就开始了另外一次gc。
 *      4. 为什么这里的方法区也能被回收
 *
 */
public class OutOfMemory {
    static class  OOMObject{

    }

    public static void main(String[] args) {
        List<OOMObject> list = new ArrayList<OOMObject>();
        while(true){
            list.add(new OOMObject());
        }

    }
}
